package sk.activities;

import java.util.ArrayList;
import java.util.List;
import sk.model.DaLaftWosFoischException;
import sk.model.Game;
import sk.model.GameType;
import sk.model.Player;
import sk.model.PlayerData;
import sk.model.Schneider;
import sk.mygui.GameStatsTableRow;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TableLayout;
import android.widget.TextView;

public class GameActivity extends Activity {

	public static final String EXTRA_PLAYER_COUNT = "ExtraPlayerCount";
	public static final String EXTRA_PLAYER_ID = "ExtraPlayerId";
	public static final String EXTRA_SUR_NAME = "ExtraSurName";
	public static final String EXTRA_PRE_NAME = "ExtraPreName";
	public static final String EXTRA_ID = "Spielid";

	private int[] tariff = { 10, 20, 50 };
	private Game game;
	private List<Player> fourPlayers, alwaysFourPlayers;
	private ListAdapter listAdapter;
	private Intent intent;
	private TextView textView, inputDescription;
	private String inputDescriptionString = "";
	private List<String> playerNames, alwaysFourNames;
	private int count = 4;
	private List<Player> availablePlayers;
	private GameInputListener gameInputListener;
	private Button endLayersButton;
	private ListView listView;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_game);
		intent = getIntent();

		int id = intent.getIntExtra(EXTRA_ID, 0);
		game = new Game(id, tariff);
		setUpAvailablePlayers();

		inputDescription = (TextView) findViewById(R.id.inputDescription);
		textView = (TextView) findViewById(R.id.gameDescription);
		endLayersButton = (Button) findViewById(R.id.gameEndLIButton);

		listView = (ListView) findViewById(R.id.gameListView);

		String[] playerList = new String[playerNames.size()];
		for (int i = 0; i < playerList.length; i++) {
			playerList[i] = playerNames.get(i);
		}

		listAdapter =
			new ArrayAdapter<String>(getApplicationContext(),
				R.layout.list_item_checkable, playerList);
		listView.setAdapter(listAdapter);
		listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

		if (availablePlayers.size() > 4) {
			gameInputListener = new GameInputListener(listView, -3);
			listView.setOnItemClickListener(gameInputListener);
		} else {
			game.setPlayers(fourPlayers);
			prepareLayers(listView);
			// prepareGameType(listView);
			gameInputListener = new GameInputListener(listView, -2);
			listView.setOnItemClickListener(gameInputListener);
		}

	}

	private class GameInputListener implements OnItemClickListener {
		private int nextMenu;
		private ListView listView;
		private int lastMenu;

		public GameInputListener(ListView listView, int nextMenu) {
			this.listView = listView;
			this.nextMenu = nextMenu;
		}

		@Override
		public void onItemClick(AdapterView<?> arg0, View arg1, int itemID,
			long arg3) {
			switch (nextMenu) {
			case -3:
				nextMenu = playerChoosen(listView, itemID);
				break;
			case -2:
				break;
			case -1:
				whoInjects(listView, itemID);
				break;
			case 0:
				setGameType(listView, itemID);
				nextMenu = 1;
				break;
			case 1:
				nextMenu = choosePlayer(listView, itemID);
				inputDescriptionString +=
					"Spieler: " + game.getPlayer().getName() + ", ";
				inputDescription.setText(inputDescriptionString);
				break;
			case 2:
				nextMenu = chooseTeamMate(listView, itemID);
				inputDescriptionString +=
					"Mitspieler: " + game.getTeamMate().getName() + ", ";
				inputDescription.setText(inputDescriptionString);
				break;
			case 4:
				setSchneider(listView, itemID);
				inputDescriptionString +=
					"Schneider: " + game.getSchneider().name() + ", ";
				inputDescription.setText(inputDescriptionString);
				nextMenu++;
				break;
			case 5:
				setRunners(listView, itemID);
				inputDescriptionString +=
					"Laufende: " + game.getRunners() + ", ";
				inputDescription.setText(inputDescriptionString);
				nextMenu++;
				break;
			case 6:
				setWinner(listView, itemID);
				break;
			}
		}

		public void nextMenuInjections() {
			inputDescriptionString += "Spritzen: ";
			lastMenu = nextMenu;
			nextMenu = -1;
			prepareInjections(listView);
		}

		public int getNextMenu() {
			return nextMenu;
		}

		public int getLastMenu() {
			return lastMenu;
		}

		public void setNextMenu(int nextMenu) {
			this.nextMenu = nextMenu;
		}

		public void nextMenuGameType(boolean ramschActive) {
			nextMenu = 0;
			prepareGameType(listView, ramschActive);
		}

		public void addLayers() {
			GameActivity.this.addLayers(listView);
		}

		public void addVirgins() {
			GameActivity.this.addVirgins(listView);
			endInput(listView);
		}
	}

	private void whoInjects(ListView listView, int itemID) {
		try {
			game.addInjection(alwaysFourPlayers.get(itemID));
			inputDescriptionString +=
				alwaysFourPlayers.get(itemID).getName() + ", ";
			inputDescription.setText(inputDescriptionString);
		} catch (DaLaftWosFoischException e) {
			listView.setItemChecked(itemID, !listView.isItemChecked(itemID));
		}
	}

	public void prepareInjections(ListView listView) {
		listAdapter =
			new ArrayAdapter<String>(getApplicationContext(),
				R.layout.list_item_checkable, alwaysFourNames);
		listView.setAdapter(listAdapter);
	}

	void addLayers(ListView listView) {
		inputDescriptionString += "gelegt: ";
		for (int i = 0; i < listView.getChildCount(); i++) {
			if (listView.isItemChecked(i)) {
				game.addLayer(fourPlayers.get(i));
				inputDescriptionString += fourPlayers.get(i).getName() + ", ";
			}
		}
		inputDescription.setText(inputDescriptionString);
	}

	void addVirgins(ListView listView) {
		for (int i = 0; i < listView.getChildCount(); i++) {
			if (listView.isItemChecked(i)) {
				game.setVirgin(fourPlayers.get(i));
			}
		}
	}

	public void endLayers(View view) {
		if (textView.getText().toString()
			.equals(getString(R.string.game_description_injections))) {
			if (gameInputListener.getLastMenu() == 0) {
				if (game.getInjections() > 0) {
					gameInputListener.nextMenuGameType(false);
				} else {
					gameInputListener.nextMenuGameType(true);
				}
			} else {
				prepareMenuAfterGameType();
			}
			endLayersButton.setVisibility(View.GONE);
		} else if (gameInputListener.getNextMenu() == -2) {
			gameInputListener.addLayers();
			gameInputListener.nextMenuGameType(true);
		} else if (gameInputListener.getNextMenu() == 7) {
			// virgins ready
			endLayersButton.setVisibility(View.GONE);
			gameInputListener.addVirgins();
		} else {
			gameInputListener.nextMenuInjections();
			textView.setText(R.string.game_description_injections);
			endLayersButton.setText(R.string.game_end_injections);
		}
	}

	private void prepareLayers(ListView listView) {
		endLayersButton.setVisibility(View.VISIBLE);
		textView.setText(R.string.game_description_layers);
		listAdapter =
			new ArrayAdapter<String>(getApplicationContext(),
				R.layout.list_item_checkable, playerNames);
		listView.setAdapter(listAdapter);
	}

	private int playerChoosen(ListView listView, int itemID) {
		int nextMenu = -3;
		if (listView.isItemChecked(itemID)) {
			alwaysFourPlayers.remove(availablePlayers.get(itemID));
			fourPlayers.remove(availablePlayers.get(itemID));
			count--;
		} else {
			alwaysFourPlayers.add(availablePlayers.get(itemID));
			fourPlayers.add(availablePlayers.get(itemID));
			count++;
		}

		// stop chosing players
		if (count == 4) {
			playerNames = new ArrayList<String>();
			for (int i = 0; i < 4; i++) {
				playerNames.add(fourPlayers.get(i).getPreName() + " "
					+ fourPlayers.get(i).getSurName());
				alwaysFourNames.add(fourPlayers.get(i).getPreName() + " "
					+ fourPlayers.get(i).getSurName());
				inputDescriptionString += fourPlayers.get(i).getName() + ", ";
				inputDescription.setText(inputDescriptionString);
			}
			game.setPlayers(fourPlayers);
			prepareLayers(listView);
			nextMenu = -2;
		}
		return nextMenu;
	}

	private void prepareGameType(ListView listView, boolean ramschActive) {
		// get game types
		GameType[] gameTypes = GameType.values();
		String[] typeStrings;
		// if (ramschActive) { TODO einbauen - Achtung: richtiges
		// auslesen des Spieltyps beachten
		typeStrings = new String[gameTypes.length];
		// } else {
		// typeStrings = new String[gameTypes.length - 1];
		// }
		int correction = 0;
		for (int i = 0; i < typeStrings.length; i++) {
			// if (!ramschActive
			// || !gameTypes[i].name().equals(GameType.RAMSCH.name())) {
			typeStrings[i + correction] = gameTypes[i].name();
			// } else {
			// correction = -1;
			// }
		}

		listAdapter =
			new ArrayAdapter<String>(getApplicationContext(),
				R.layout.list_item, typeStrings);
		listView.setAdapter(listAdapter);
		textView.setText(R.string.game_description_game);

		endLayersButton.setText(R.string.game_add_injections);
	}

	private void buildTable() {

		TableLayout table = (TableLayout) findViewById(R.id.game_table);

		GameStatsTableRow[] tableRows =
			new GameStatsTableRow[game.getPlayers().size()];

		for (int i = 0; i < game.getPlayers().size(); i++) {
			tableRows[i] = new GameStatsTableRow(this);
			Player player = game.getPlayers().get(i).getPlayer();
			tableRows[i].create(
				player.getPreName() + " " + player.getSurName(),
				game.getResult(player));
			table.addView(tableRows[i]);
		}

		table.setVisibility(View.VISIBLE);
	}

	private void endInput(ListView listView) {

		listView.setVisibility(View.GONE);
		textView.setText(R.string.game_ready);
		Button saveGame = (Button) findViewById(R.id.okButton);
		saveGame.setVisibility(View.VISIBLE);
		buildTable();

	}

	public void closeGameActivity(View view) {
		Intent returnIntent = new Intent(this, SessionActivity.class);
		returnIntent.putExtra(SessionActivity.EXTRA_GAME, game.toString());
		setResult(RESULT_OK, returnIntent);
		finish();
	}

	private void setWinner(ListView listView, int itemID) {
		if (itemID == 0) {
			game.setWon(true);
		} else {
			game.setWon(false);
		}
		endInput(listView);

	}

	private void setGameType(ListView listView, int itemID) {
		game.setGameType(GameType.values()[itemID]);
		inputDescriptionString += game.getType().name() + ", ";
		inputDescription.setText(inputDescriptionString);

		prepareMenuAfterGameType();
	}

	private void prepareMenuAfterGameType() {
		listAdapter =
			new ArrayAdapter<String>(getApplicationContext(),
				R.layout.list_item, playerNames);
		listView.setAdapter(listAdapter);
		if (game.getType() == GameType.RAMSCH) {
			textView.setText(R.string.game_description_looser);
		} else if (game.getType() == GameType.MISDEAL) {
			textView.setText(R.string.game_description_misdeal);

			if (availablePlayers.size() > 0) {
				String[] avaPlayers = new String[availablePlayers.size()];
				for (int i = 0; i < avaPlayers.length; i++) {
					avaPlayers[i] =
						availablePlayers.get(i).getPreName() + " "
							+ availablePlayers.get(i).getSurName();
				}
				listAdapter =
					new ArrayAdapter<String>(getApplicationContext(),
						R.layout.list_item, avaPlayers);
				listView.setAdapter(listAdapter);
			}
		} else {
			textView.setText(R.string.game_description_player);
		}
		gameInputListener.setNextMenu(1);
	}

	private int choosePlayer(ListView listView, int itemID) {
		endLayersButton.setVisibility(View.GONE);
		if (availablePlayers.size() > 0 && game.getType() == GameType.MISDEAL) {
			boolean playerInList = false;
			for (PlayerData pD : game.getPlayers()) {
				if (pD.getPlayer().equals(availablePlayers.get(itemID))) {
					playerInList = true;
				}
			}

			Player[] opponents;
			if (!playerInList) {
				game.getPlayers().add(
					new PlayerData(availablePlayers.get(itemID)));

				opponents = new Player[4];
				for (int i = 0; i < opponents.length; i++) {
					opponents[i] = fourPlayers.get(i);
				}
			} else {
				fourPlayers.remove(availablePlayers.get(itemID));
				opponents = new Player[3];
				opponents[0] = fourPlayers.get(0);
				opponents[1] = fourPlayers.get(1);
				opponents[2] = fourPlayers.get(2);
			}
			game.setPlayer(availablePlayers.get(itemID));

			game.setOpponents(opponents);

			endInput(listView);
			return 8;
		}
		game.setPlayer(fourPlayers.get(itemID));
		fourPlayers.remove(itemID);
		playerNames.remove(itemID);
		listView.setAdapter(listAdapter);

		if (game.getType() == GameType.SAUSPIEL) {
			textView.setText(R.string.game_description_teammate);
			return 2; // goto choose team mate
		} else {
			Player[] opponents = new Player[3];
			opponents[0] = fourPlayers.get(0);
			opponents[1] = fourPlayers.get(1);
			opponents[2] = fourPlayers.get(2);
			game.setOpponents(opponents);

			if (game.getType() == GameType.RAMSCH) {
				listAdapter =
					new ArrayAdapter<String>(getApplicationContext(),
						R.layout.list_item_checkable, playerNames);
				listView.setAdapter(listAdapter);
				listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

				textView.setText(R.string.game_description_virgins);
				endLayersButton.setText(R.string.game_end_virigins);
				endLayersButton.setVisibility(View.VISIBLE);
				return 7; // all input done apart from virgins
			} else if (game.getType() == GameType.MISDEAL) {
				endInput(listView);
				return 8;
			} else {
				setUpSchneiderList(listView);
				return 4; // goto Schneider
			}
		}
	}

	private int chooseTeamMate(ListView listView, int itemID) {
		game.setTeamMate(fourPlayers.get(itemID));
		fourPlayers.remove(itemID);
		playerNames.remove(itemID);
		Player[] opp = new Player[2];
		opp[0] = fourPlayers.get(0);
		opp[1] = fourPlayers.get(1);
		game.setOpponents(opp);
		setUpSchneiderList(listView);
		return 4; // goto Schneider
	}

	private void setUpSchneiderList(ListView listView) {
		textView.setText(R.string.game_description_schneider);
		Schneider[] schneiders = Schneider.values();
		String[] schneiderStrings = new String[schneiders.length];
		for (int i = 0; i < schneiderStrings.length; i++) {
			schneiderStrings[i] = schneiders[i].name();
		}
		listAdapter =
			new ArrayAdapter<String>(getApplicationContext(),
				R.layout.list_item, schneiderStrings);
		listView.setAdapter(listAdapter);
	}

	private void setSchneider(ListView listView, int itemID) {
		game.setSchneider(Schneider.values()[itemID]);

		String[] runners;
		if (game.getType() == GameType.WENZ) {
			runners = new String[4];
			runners[0] = "0";
			for (int i = 2; i < runners.length + 1; i++) {
				runners[i - 1] = "" + i;
			}
		} else if (game.getType() == GameType.SOLO) {
			runners = new String[7];
			runners[0] = "0";
			for (int i = 3; i < runners.length + 2; i++) {
				runners[i - 2] = "" + i;
			}
		} else {
			runners = new String[13];
			runners[0] = "0";
			for (int i = 3; i < runners.length + 2; i++) {
				runners[i - 2] = "" + i;
			}
		}
		listAdapter =
			new ArrayAdapter<String>(getApplicationContext(),
				R.layout.list_item, runners);
		listView.setAdapter(listAdapter);
		textView.setText(R.string.game_description_runners);
	}

	private void setRunners(ListView listView, int itemID) {
		if (itemID == 0) {
			game.setRunners(0);
		} else if (game.getType() == GameType.WENZ) {
			game.setRunners(itemID + 1);
		} else {
			game.setRunners(itemID + 2);
		}
		textView.setText(R.string.game_description_winner);
		String[] strings = { "Spieler", "Nicht-Spieler" };
		listAdapter =
			new ArrayAdapter<String>(getApplicationContext(),
				R.layout.list_item, strings);
		listView.setAdapter(listAdapter);
	}

	private void setUpAvailablePlayers() {
		count = intent.getIntExtra(EXTRA_PLAYER_COUNT, 4);
		fourPlayers = new ArrayList<Player>();
		availablePlayers = new ArrayList<Player>();
		alwaysFourPlayers = new ArrayList<Player>();
		playerNames = new ArrayList<String>();
		alwaysFourNames = new ArrayList<String>();

		for (int i = 0; i < count; i++) {
			String preName = intent.getStringExtra(EXTRA_PRE_NAME + i);
			String surName = intent.getStringExtra(EXTRA_SUR_NAME + i);
			int id = intent.getIntExtra(EXTRA_PLAYER_ID + i, 0);
			Player player = new Player(preName, surName, id);
			fourPlayers.add(player);
			alwaysFourPlayers.add(player);
			if (count != 4) {
				availablePlayers.add(player);
			}
			playerNames.add(preName + " " + surName);
		}
	}
}
